package me.zhengjie.threePlc;

import lombok.RequiredArgsConstructor;
import me.zhengjie.agvSend.AgvSendService;
import me.zhengjie.pojo.dto.NoticeAgvDto;
import me.zhengjie.pojo.entity.WcsAgvReleaseGoods;
import me.zhengjie.pojo.entity.WcsLineBodyInbound;
import me.zhengjie.pojo.entity.WcsLineBodyOutbound;
import me.zhengjie.sqlservice.WcsAgvReleaseGoodsService;
import me.zhengjie.sqlservice.WcsLineBodyOutboundService;
import me.zhengjie.sqlservice.WcsLineBodyInboundService;
import me.zhengjie.state.MaterialStatus;
import me.zhengjie.state.TaskStatus;
import me.zhengjie.state.TaskType;
import me.zhengjie.tcp.InboundLineBody;
import me.zhengjie.tcp.OutboundLineBody;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;

@Component
@RequiredArgsConstructor
public class AgvReleaseGoodsTiming {
    private static final Logger log = LoggerFactory.getLogger(AgvReleaseGoodsTiming.class);
    private final WcsAgvReleaseGoodsService wcsAgvReleaseGoodsService;

    private final WcsLineBodyInboundService wcsLineBodyInboundService;

    private final WcsLineBodyOutboundService wcsLineBodyOutboundService;

    private final InboundLineBody inboundLineBody;

    private final OutboundLineBody outboundLineBody;

    private final AgvSendService agvSendService;

    @Scheduled(fixedDelay = 1000)
    @Transactional
    public void agvReleaseGoodsTiming(){

        try {
            List<WcsAgvReleaseGoods> wcsAgvReleaseGoodsList = wcsAgvReleaseGoodsService.selectFloor(TaskType.THREE_FLOOR.getStatus(),1);
            if (!wcsAgvReleaseGoodsList.isEmpty()){
                for (WcsAgvReleaseGoods wcsAgvReleaseGoods : wcsAgvReleaseGoodsList) {
                    Integer id = wcsAgvReleaseGoods.getId();
                    String taskCode = wcsAgvReleaseGoods.getTaskCode();
                    Integer pattern = wcsAgvReleaseGoods.getPattern();
                    if (Objects.equals(TaskStatus.PATTERN_ANTI_CARGO.getStatus(), pattern)){
                        WcsLineBodyOutbound wcsLineBodyOutbound = wcsLineBodyOutboundService.selectOne();
                        //查询3楼放货表，plc允许放货后，通知AGV放货
                        log.info("3楼出库放货请求放货：{}",wcsLineBodyOutbound);
                        if (wcsLineBodyOutbound!=null){
                            Integer plcStatus = outboundLineBody.readHoldingRegisters(1, 1);
                            if (plcStatus ==2){
                                Integer wcsLineBodyOutboundListId = wcsLineBodyOutbound.getId();
                                Integer unitId = wcsLineBodyOutbound.getUnitId();
                                Integer oneRequestPut = wcsLineBodyOutbound.getOneRequestPut();
                                Integer oneTeturnResult = wcsLineBodyOutbound.getOneTeturnResult();
                                Integer oneAddress = wcsLineBodyOutbound.getOneAddress();
                                Integer readHoldingRegisters = outboundLineBody.readHoldingRegisters(oneRequestPut, unitId);
                                Integer readHoldingRegisters1 = outboundLineBody.readHoldingRegisters(oneAddress, unitId);
                                log.info("PLC是否请求放货:{}，第一段是否有货：{}", readHoldingRegisters,readHoldingRegisters1);
                                if (readHoldingRegisters == 1 && readHoldingRegisters1 == 0) {
    //                        if (true) {
                                    //通知agv放货
                                    boolean b2 = outboundLineBody.writeWithRetry(oneTeturnResult, 1, unitId, MaterialStatus.RETRY_COUNT.getStatus());
                                    if (!b2){
                                        log.error("3楼出库放货失败，写入plc失败");
                                        throw new RuntimeException("3楼出库放货失败，写入plc失败");
                                    }
                                    NoticeAgvDto noticeAgvDto = new NoticeAgvDto();
                                    noticeAgvDto.setTaskCode(taskCode);
                                    noticeAgvDto.setActionStatus("6");
                                    noticeAgvDto.setEqptCode("1");
                                    boolean b = agvSendService.noticeAgv(noticeAgvDto);
                                    if (b){
                                        log.info("PLC允许放货地址位：{},任务号：{},时间：{}",oneTeturnResult,taskCode, LocalDateTime.now());
                                        //修改标记为1
    //                                boolean b3 = wcsLineBodyOutboundService.updateOneWritePlc(wcsLineBodyOutboundListId, 1);
                                        //删除放货表
                                        boolean b1 = wcsAgvReleaseGoodsService.delete(id);
                                    }
                                }
                            }
                        }
                    }else
                        if (Objects.equals(TaskStatus.INBOUND_PATTERN_ANTI_CARGO.getStatus(), pattern)){
                        WcsLineBodyInbound wcsLineBodyInbound = wcsLineBodyInboundService.selectOne();
                        if (wcsLineBodyInbound !=null){
                            Integer unitId = wcsLineBodyInbound.getUnitId();
                            Integer inbOneChainMachine = wcsLineBodyInbound.getInbOneChainMachine();
                            Integer inbOneChainMachineResult = wcsLineBodyInbound.getInbOneChainMachineResult();
                            Integer inbOneChainMachineStatus = inboundLineBody.readHoldingRegisters(inbOneChainMachine, unitId);
                            log.info("3楼入库链条放货:{}",inbOneChainMachineStatus);
                            if (inbOneChainMachineStatus == 1){
                                Integer plcStatus = inboundLineBody.readHoldingRegisters(1, 1);
                                if (plcStatus == 2){
                                    boolean b2 = inboundLineBody.writeWithRetry(inbOneChainMachineResult, 1, unitId, MaterialStatus.RETRY_COUNT.getStatus());
                                    if (!b2){
                                        log.error("3F入库到线体失败，写入PLC失败");
                                        throw new RuntimeException("3F入库到线体失败，写入PLC失败");
                                    }
                                    log.info("3F入库发生PLC：{}",inboundLineBody);
                                    //通知agv放货
                                    NoticeAgvDto noticeAgvDto = new NoticeAgvDto();
                                    noticeAgvDto.setTaskCode(taskCode);
                                    noticeAgvDto.setActionStatus("6");
                                    noticeAgvDto.setEqptCode("3");
                                    boolean b = agvSendService.noticeAgv(noticeAgvDto);
                                    log.info("3F入库AGV结果{}",b);
                                    if (b){
                                        //删除放货表
                                        boolean b1 = wcsAgvReleaseGoodsService.delete(id);
                                    }
                                }
                            }
                        }
                    }

                }
            }
        } catch (RuntimeException e) {
            log.error("AGV放货失败",e);
            throw new RuntimeException(e);
        }
    }
}
